﻿using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using CADTool.DotNetARX;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CADTool
{
    public static class 好朋友分组法class
    {
        public class 小朋友
        {
            public int myid;
            public List<小朋友> 我们的朋友;
            public 小朋友(int id)
            {
                myid = id;
                我们的朋友 = new List<小朋友>();
            }
        }
        /// <summary>
        /// 测试
        /// </summary>
        public static void 好朋友分组法()
        {
            List<Circle> cirs = Z.PinkList<Circle>();
            if (cirs.Count == 0) return;
            //先把圆创建成我们定义好的小朋友
            List<小朋友> xpys = new List<小朋友>();
            for (int i = 0; i < cirs.Count; i++)
            {
                小朋友 one = new 小朋友(i);
                xpys.Add(one);
            }
            //把他们的朋友关系添加进他们的朋友圈
            //做一个双循环遍历，询问他们的朋友关系
            for (int i = 0; i < xpys.Count; i++)
            {
                var a = xpys[i]; //小朋友a
                //这里我们用包围盒碰撞来代表他们的朋友关系
                //只要两个圆的包围盒子碰撞了，就说明他们是朋友关系
                for (int j = 0; j < xpys.Count; j++)
                {
                    if (i == j) continue;//自己就不用问了
                    var b = xpys[j]; //小朋友b
                    if (cirs[a.myid].GeometricExtents.ExtensHit(cirs[b.myid].GeometricExtents))
                    {
                        //互加好友
                        a.我们的朋友.Add(b);
                        b.我们的朋友.Add(a);
                    }
                }
            }
            List<List<小朋友>> 分组 = new List<List<小朋友>>();
            //接下来我们进行分组
            while (xpys.Count > 0)
            {
                //先把第一个小朋友拎出来
                var first = xpys.First();
                xpys.RemoveAt(0);
                //显然他就是第一组的第一个成员
                List<小朋友> 一组 = new List<小朋友>();
                一组.Add(first);
                //然后我们建立一个队列
                Queue<小朋友> 排队询问 = new Queue<小朋友>();
                //把第一个小朋友的好朋友加到队列中
                foreach (var py in first.我们的朋友)
                {
                    xpys.Remove(py);
                    排队询问.Enqueue(py);
                }
                //接下来我们对队列中的小朋友挨个询问他的朋友都有谁
                //然后把他的朋友加到队列的尾部
                //然后让他进入分组中，再询问下一个
                //询问队伍中的第一个小朋友，把他的朋友加到队伍的末尾，让他离开队伍，去到分组里
                //直到这个队伍里没人，这一组就建立成功了
                while (排队询问.Count > 0)
                {
                    var one = 排队询问.Dequeue(); //第一个小朋友出列
                    foreach (var py in one.我们的朋友)
                    {
                        //先把这个小朋友加到分组里
                        一组.Add(one);
                        //先问问他的朋友是否已经在组里了，如果在组里就不用排队了
                        //如果已经在队列里面了，也不会排队
                        //如果他的好朋友没有在分组里也没有在队列里，就加到队伍里
                        if (!一组.Contains(py))
                        {
                            xpys.Remove(py);
                            排队询问.Enqueue(py);
                        }
                    }
                }
                //此时一组建立完成，把一组加到分组里
                分组.Add(一组);
                //分组完成，我们来合并包围盒看看效果
                foreach (var yizu in 分组)
                {
                    Extents3d ext = new Extents3d();
                    foreach (var yi in yizu)
                    {
                        ext.AddExtents(cirs[yi.myid].GeometricExtents);
                    }
                    Z.EntityAddModelSpace(ext.ExtentsPolyline());
                }
            }
        
        }

    }
}
